"""
属性私有化
访问范围的改变
3种变量
a       -->public
_a      -->protected
__a     -->private
不但适用于属性，也适用于方法

区域
类内部
子类内部
模块内其他位置
跨模块访问
"""
#继承关系
#在18-19行内，算类的内部
class Animal:
    a = 10
    _b = 10
    __c = 10
    def test(self):
        print(Animal.a)
        print(self.a)

    def testProtected(self):
        print(Animal._b)
        print(self._b)

    def testPrivate(self):
        print(Animal.__c)
        print(self.__c)
    pass

#在22到23行，算子类内部。子类以外的部分称为模块内部的其他位置，如果换了一个文件，则称为模块外部比如test1
class Dog(Animal):
    def test2(self):
        print(Dog.a)
        print(self.a)
    def test2Protected(self):
        print(Dog._b)
        print(self._b)

    def test2Private(self):
        print(Dog.__c)
        print(self.__c)


    def __eat(self):
        print('eat')
    pass


 a = Animal()
 a.test()
 print("------------------------------")
 d = Dog()
 d.test2()
 print("------------------------------")
 print(Dog.a)
 print(Animal.a)
 print(d.a)
 print(a.a)
 b=100

 a = Animal()
 d = Dog()
 print("------------------------------")
 a.testProtected()
 d.test2Protected()
 print("------------------------------")
 """会有警告，但是依旧可以访问"""
 print(Dog._b)
 print(Animal._b)
 print(a._b)
 print(d._b)

# __all__ = ["_b","Animal"]
# _b = 100

a = Animal()
d = Dog()
print("------------------------------")
# a.testPrivate()
# d.test2Private()
"""
python无法实现真正的私有，__x的实质是将原有变量名改为一个新的名称 如_类名__x
假如说子类也有相同的变量名，那么你用__来私有化可能回面临重复的可能性，所以需要加上子类同名属性防止被覆盖，另一个作用是防止外界的直接访问
"""
# print(Animal.__c)
"""
print(Animal.__dict__)
print(Animal._Animal__c)
"""
# print(Animal.__dict__)
# print(Animal._Animal__c)
# print(Dog.__c)
# print(a.__c)
# print(d.__c)
# """没有private的变量，还是protected的属性，可以理解成_ _c，遵循protected的所有特性"""
# __all__ = ["__c"]
# __c = 100

"""
规范
如果你很需要用到某些变量名但是又是系统的关键字
可以用 x_ 比如class_

系统内置的一些方法一般会用
__dict__
这种命名方式请避免
"""

# d.eat()
# d.__eat()
# print(Dog.__dict__)
# d._Dog__eat()